package com.bestcem.xm.user.util.business;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bestcem.xm.user.config.properties.SettingProperties;
import com.bestcem.xm.user.constant.CommonConstant;
import com.bestcem.xm.user.service.dto.OperationDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * 加载权限
 *
 * @author Linked <zhijian.lin@idiaoyan.com>
 * @version v1.0
 * @date 2022/3/17 16:52
 */
@Slf4j
@Component
public class UserPermissionUtil implements InitializingBean {

    @Resource
    private SettingProperties settingProperties;

    /**
     * 权限map
     */
    private Map<String, Map<String, List<String>>> resourceMap;

    /**
     * 权限
     */
    private String permission;


    private SortedMap<String, Map<String, List<String>>> loadResourceMap() {
        try {
            File jsonFile = ResourceUtils.getFile("classpath:json/permission.json");
            String resource = FileUtil.readString(jsonFile, "utf-8");
            permission = resource;
            return convertResMap(resource);
        } catch (FileNotFoundException e) {
            log.error("加载USER权限json文件失败");
        }
        return Collections.emptySortedMap();
    }

    /**
     * 可跳过不进行处理的模块操作名称列表
     */
    private static final List<String> skipList = Arrays.asList("subsystem", "remark");

    private SortedMap<String, Map<String, List<String>>> convertResMap(String resource) {
        // 解析资源树前两层map
        Map<String, Map<String, String>> resMap = JSON.parseObject(resource,
                new TypeReference<Map<String, Map<String, String>>>() {
                });
        // 最终解析后的权限map
        Map<String, Map<String, List<String>>> resultPermMap = new HashMap<>();
        for (Map.Entry<String, Map<String, String>> resourceEntry : resMap.entrySet()) {
            // 模块名称
            String permModelName = resourceEntry.getKey();
            for (Map.Entry<String, String> permModelDataEntry : resourceEntry.getValue().entrySet()) {
                // 模块的操作名称
                String operationName = permModelDataEntry.getKey();
                // 如果是可跳过的，则跳过
                if (skipList.contains(operationName)) {
                    continue;
                }
                // 解析为资源对象列表
                List<OperationDTO> operationList = JSON.parseArray(permModelDataEntry.getValue(), OperationDTO.class);
                for (OperationDTO opObj : operationList) {
                    List<String> resList = opObj.getResource();
                    List<String> opList = opObj.getOperation();
                    if (CollectionUtils.isNotEmpty(opList) && opList.contains(CommonConstant.ALL_PERIMISSION_CONSTANT)) {
                        opList = Collections.singletonList(CommonConstant.ALL_PERIMISSION_CONSTANT);
                    }
                    if (CollectionUtils.isNotEmpty(resList)) {
                        for (String res : resList) {
                            res = StringUtils.strip(res, "/");
                            if (res.endsWith("$")) {
                                res = StringUtils.stripEnd(res, "$");
                                res = StringUtils.stripEnd(res, "*");
                                res = StringUtils.stripEnd(res, ".");
                                res = StringUtils.stripEnd(res, "/");
                                res += ".*$";
                                res = res.replace("/([a-fA-F0-9]{24})", "(/[a-fA-F0-9]{24})?");
                            }
                            Map<String, List<String>> opMap = resultPermMap.getOrDefault(res, new HashMap<>());
                            for (String op : opList) {
                                List<String> permList = opMap.getOrDefault(op, new ArrayList<>());
                                permList.add(String.format("%s.%s", permModelName, operationName));
                                opMap.put(op, permList);
                            }
                            // api/bi/worktables/([a-f0-9A-F]{24})?.*$ -> HTTP/DELETE -> ANALYSIS_WORKSHEET.WORKSHEET.DELETE
                            resultPermMap.put(res, opMap);
                        }
                    }
                }
            }
        }
        // 权限按key的长度排序
        SortedMap<String, Map<String, List<String>>> sortPermission = new TreeMap<>((k1, k2) -> {
            if (k1.length() > k2.length()) {
                return -1;
            }
            return 1;
        });
        sortPermission.putAll(resultPermMap);
        return sortPermission;
    }

    private Map<String, Map<String, List<String>>> getResourceMap() {
        return this.resourceMap;
    }

    @Override
    public void afterPropertiesSet() {
        this.resourceMap = loadResourceMap();
    }

    public Set<String> getHandlerPermissions(String method, String url) {
        String operation = "HTTP/" + method;
        url = StringUtils.strip(url, "/");
        Set<String> permSet = new HashSet<>();
        for (Map.Entry<String, Map<String, List<String>>> entry : getResourceMap().entrySet()) {
            String resourcePath = entry.getKey();
            if (resourcePath.endsWith("$")) {
                if (!url.matches(resourcePath)) {
                    continue;
                }
            } else {
                if (!url.equals(resourcePath)) {
                    continue;
                }
            }
            List<String> allPerms = entry.getValue().get("*");
            if (CollectionUtils.isNotEmpty(allPerms)) {
                permSet.addAll(allPerms);
            }
            List<String> opPerms = entry.getValue().get(operation);
            if (CollectionUtils.isNotEmpty(opPerms)) {
                permSet.addAll(opPerms);
            }
            // 匹配一次就跳出循环
            break;
        }
        return permSet;
    }

    /**
     * 获取所有权限
     *
     * @return Map<Map < List < String>>>
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/4/15 10:32
     */
    public Map<String, Map<String, List<String>>> getAllPermission1() {
        return getResourceMap();
    }

    /**
     * 获取所有权限
     *
     * @param
     * @return com.alibaba.fastjson.JSONObject
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/26 19:01
     */
    public JSONObject getAllPermission() {
        JSONObject jsonObject = JSON.parseObject(this.permission);
        JSONObject per = new JSONObject();
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            JSONObject permissionJson = (JSONObject) entry.getValue();
            List<String> array = new ArrayList<>();
            for (Map.Entry<String, Object> perEntry : permissionJson.entrySet()) {
                if (!"subsystem".equals(perEntry.getKey())) {
                    array.add(perEntry.getKey());
                }
            }
            per.put(entry.getKey(), array);
        }
        return per;
    }

}
